package entity;

import java.io.IOException;
import java.util.Calendar;
import java.util.GregorianCalendar;

import javax.xml.bind.JAXBException;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;

import org.xml.sax.SAXException;

import settings.IdManager;
import settings.Settings;

/**
 * 
 * @author A0083955R
 * 
 */
@XmlRootElement
public class Goal extends XMLentity {
	private String id;
	private String name;
	private Calendar startDate = new GregorianCalendar();
	private Calendar endDate = new GregorianCalendar();
	private double totalAmount;
	private String comment;
	private double amountAchieved;
	private boolean isActive;
	private boolean isAchieved;
	
	private double requireAmount;

	private final String rootKey = "goal";

	public Goal() {
		this.setId("NULL");
		this.setName("NULL");
		this.setStartDate(null);
		this.setEndDate(null);
		this.setTotalAmount(0);
		this.setAmountAchieved(0);
		this.setComment("NULL");
		this.setActive(false);
		this.setRequireAmount(0);
		this.setAchieved(false);
	}

	public Goal(String _name, Calendar _startDate, Calendar _endDate,
			double _totalAmount, double _amountAchieved, String _comment,
			boolean _active, boolean _achieved) throws TransformerConfigurationException,
			InstantiationException, IllegalAccessException, JAXBException,
			ParserConfigurationException, SAXException, IOException,
			TransformerException {

		/*this.setId(IdManager.getInstance().getLastId(rootKey));
		IdManager.getInstance().updateLastId(rootKey);
		*/
		this.setId(null);
		this.setName(_name);
		this.setStartDate(_startDate);
		this.setEndDate(_endDate);
		this.setTotalAmount(_totalAmount);
		this.setAmountAchieved(_amountAchieved);
		this.setComment(_comment);
		this.setActive(_active);
		this.calculateRequireAmt();
		this.setAchieved(_achieved);
	}
	/**
	 * @author A0083955R Ding Sen
	 */
	public String getId() {
		return id;
	}
	/**
	 * @author A0083955R Ding Sen
	 */
	@XmlAttribute
	public void setId(String _id) {
		this.id = _id;
	}
	/**
	 * @author A0083955R Ding Sen
	 */
	public String getName() {
		return name;
	}
	/**
	 * @author A0083955R Ding Sen
	 */
	@XmlAttribute
	public void setName(String _name) {
		this.name = _name;
	}
	/**
	 * @author A0083955R Ding Sen
	 */
	public Calendar getStartDate() {
		return startDate;
	}
	/**
	 * @author A0083955R Ding Sen
	 */
	public void setStartDate(Calendar _startDate) {
		if(_startDate != null)
			this.startDate.set(_startDate.get(Calendar.YEAR), _startDate.get(Calendar.MONTH), _startDate.get(Calendar.DATE));
	}
	/**
	 * @author A0083955R Ding Sen
	 */
	public Calendar getEndDate() {
		return endDate;
	}

	/**
	 * @author A0083955R Ding Sen
	 */
	public void setEndDate(Calendar _endDate) {
		if(_endDate != null)
			this.endDate.set(_endDate.get(Calendar.YEAR), _endDate.get(Calendar.MONTH), _endDate.get(Calendar.DATE));
	}
	/**
	 * @author A0083955R Ding Sen
	 */
	public double getTotalAmount() {
		return totalAmount;
	}
	/**
	 * @author A0083955R Ding Sen
	 */
	@XmlAttribute
	public void setTotalAmount(double _totalAmount) {
		this.totalAmount = _totalAmount;
	}
	/**
	 * @author A0083955R Ding Sen
	 */
	public String getComment() {
		return comment;
	}
	/**
	 * @author A0083955R Ding Sen
	 */
	@XmlAttribute
	public void setComment(String _comment) {
		this.comment = _comment;
	}
	/**
	 * @author A0083955R Ding Sen
	 */
	public double getAmountAchieved() {
		return amountAchieved;
	}
	/**
	 * @author A0083955R Ding Sen
	 */
	@XmlAttribute
	public void setAmountAchieved(double _amountAchieved) {
		this.amountAchieved = _amountAchieved;
	}
	/**
	 * @author A0083955R Ding Sen
	 */
	public void depositToGoal(double _amt)
	{
		this.amountAchieved += _amt;
	}
	/**
	 * @author A0083955R Ding Sen
	 */
	public boolean isActive() {
		return isActive;
	}
	/**
	 * @author A0083955R Ding Sen
	 */
	@XmlAttribute
	public void setActive(boolean _isActive) {
		this.isActive = _isActive;
	}
	/**
	 * @author A0083955R Ding Sen
	 */
	@XmlAttribute
	public void setRequireAmount(double _requireAmount)
	{
		requireAmount = _requireAmount;	
	}
	/**
	 * @author A0083955R Ding Sen
	 */
	public double getRequireAmount()
	{
		return requireAmount;
	}
	/**
	 * @author A0083955R Ding Sen
	 */
	public void calculateRequireAmt()
	{
		int duration = Settings.daysBetween(this.startDate, this.endDate);
		double amt = new Double(Settings.doubleTo2DP(((this.totalAmount - this.amountAchieved) / duration)));
		this.setRequireAmount(amt);
	}
	/**
	 * @author A0083955R Ding Sen
	 */
	public void calculateRequireAmt(Calendar newDay)
	{
		int duration = Settings.daysBetween(newDay, this.endDate);
		double amt = new Double(Settings.doubleTo2DP(((this.totalAmount - this.amountAchieved) / duration)));
		this.setRequireAmount(amt);
	}
	/**
	 * @author A0083955R Ding Sen
	 */
	public String toString()
	{
		return (id + ", " + name + ", " + Settings.getInstance().df.format(startDate.getTime()) + ", " + Settings.getInstance().df.format(endDate.getTime()) + ", " + totalAmount + ", " + Settings.doubleTo2DP(amountAchieved) + ", " + comment + ", " + isActive + ", " + isAchieved);
	}
	/**
	 * @author A0083955R Ding Sen
	 */
	public boolean isAchieved() {
		return isAchieved;
	}
	/**
	 * @author A0083955R Ding Sen
	 */
	@XmlAttribute
	public void setAchieved(boolean isAchieved) {
		this.isAchieved = isAchieved;
	}
}